C++ 异常处理

这本书的模板和 I/O 流类库只是随便看了下, 这篇可能是最后一篇笔记了.

以前写过简单的 Python , 那时候感觉异常处理只是防止程序出错而异常终止, 只要把可能出错的代码放到 try 里面就行了, 并不会对异常做什么处理. 更不知道把异常看作一个对象.

看到有人说不推荐 C++ 的异常处理, 但是那又如何, 我都不会用.

一. 错误导致异常

发生异常是因为产生了错误, 错误有两种, 一种是编译错误, 也就是语法错误, 编译通不过更没法运行. 另一种是运行错误, 运行错误又包括两种, 一种是逻辑错误, 这种是代码写得不好, 有逻辑漏洞, 比如考虑不周到, 另一个种是运行异常. 这种情况通常是可以预料但无法避免, 比如你知道空间分配可能失败, 但是你的程序怎么能保证一定可以分配空间?

二. 异常处理的思想

我明知道有些事会出错, 所以我就抱着试一试的态度去做, 如果成功了就好. 如果没成功我就向领到报告, 把异常情况告诉他, 同时把我做的半成品都给扔掉.

1
2
3
4
5
6
7
8
9
10
try
{
//试着做某事
if(发生了错误)
抛出异常
}
catch(某个问题) //领导收到某个问题
{
//想办法解决问题
}

三. 异常处理的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>

using namespace std;

/*
2017年10月31日 16:58:28
使用异常处理来处理错误
*/

int dive(int x, int y);

int main(int argc, char const *argv[])
{
try
{
cout<<"5/2 = "<<dive(5, 2)<<endl;
cout<<"8/0 = "<<dive(8, 0)<<endl;
//这里抛出了一个 int 类型的异常, try 后面的就不执行了, 直接捕获异常
cout<<"7/1 = "<<dive(7, 1)<<endl;
}
catch(int) //捕获异常
{
cout<<"Except of deviding zero."<<endl;
}
cout<<"End of program"<<endl;

return 0;
}

int dive(int x, int y)
{
if(y==0)
{
throw y; //抛出异常
}
return x/y;
}

运行结果:
5/2 = 2
Except of deviding zero.
End of program
请按任意键继续. . .

四. 异常接口声明

调用可能会抛出异常的函数是危险的, 所以最好能列出函数可能会抛出的异常.
异常接口声明也称为抛出表列, 给出了并限制了可能抛出的异常.

  • <返回类型> funname(<形参表列>)throw(T1, T2, T3..);
    这个函数原型指定了 funname 可以抛出的类型为 T1, T2, T3..也可以抛出它们的子类, 如果抛出其他异常, 系统将调用 abort 函数终止程序.

  • <返回类型> funname(<形参表列>)throw();
    函数原型的抛出列表是一个空表, 表示该函数不抛出任何类型的异常.

  • <返回类型> funname(<形参表列>);
    如果函数原型没有 throw 说明, 表示该函数可以抛出任意类型的异常.

五. 定义自己的异常类

C++ 标准库中定义了异常类, 我们可以根据需要定义自己的异常类.
异常类也是类, 可以用成员变量保存错误信息, 通过成员函数返回错误信息.
(书上的例子不够简单, 不给了)